/**
 * 权限校验 Composable
 * 支持从 Token 中解析权限信息并进行校验
 */

import { computed } from 'vue';

import { useAccessStore } from '@vben/stores';

import {
  extractPermissionsFromToken,
  hasAllRolesInToken,
  hasAnyRoleInToken,
  hasPermissionInToken,
  hasRoleInToken,
  parseJwtToken,
} from '#/utils/token';

export function usePermission() {
  const accessStore = useAccessStore();

  /**
   * 当前 Token
   */
  const token = computed(() => accessStore.accessToken || '');

  /**
   * Token 载荷
   */
  const tokenPayload = computed(() => {
    if (!token.value) return null;
    return parseJwtToken(token.value);
  });

  /**
   * 当前用户的所有权限编码
   */
  const permissions = computed(() => {
    if (!token.value) {
      return {
        buttonPermCodes: [],
        menuPermCodes: [],
        urlPermCodes: [],
        allPermCodes: [],
      };
    }
    return extractPermissionsFromToken(token.value);
  });

  /**
   * 当前用户的角色列表
   */
  const roles = computed(() => {
    return tokenPayload.value?.roles || [];
  });

  /**
   * 当前用户信息
   */
  const userInfo = computed(() => {
    if (!tokenPayload.value) return null;
    return {
      userId: tokenPayload.value.userId,
      username: tokenPayload.value.username,
      roles: tokenPayload.value.roles,
    };
  });

  /**
   * 检查是否拥有指定权限
   * @param permissionCode 权限编码（如：'user:delete'）
   * @param type 权限类型：'button' | 'menu' | 'url' | 'any'（默认 'any'）
   * @returns true 表示拥有权限，false 表示没有权限
   */
  function hasPermission(
    permissionCode: string,
    type: 'button' | 'menu' | 'url' | 'any' = 'any',
  ): boolean {
    if (!token.value) return false;
    return hasPermissionInToken(token.value, permissionCode, type);
  }

  /**
   * 检查是否拥有任一指定权限
   * @param permissionCodes 权限编码数组
   * @param type 权限类型：'button' | 'menu' | 'url' | 'any'（默认 'any'）
   * @returns true 表示拥有任一权限，false 表示没有任何权限
   */
  function hasAnyPermission(
    permissionCodes: string[],
    type: 'button' | 'menu' | 'url' | 'any' = 'any',
  ): boolean {
    if (!token.value) return false;
    return permissionCodes.some((code) =>
      hasPermissionInToken(token.value, code, type),
    );
  }

  /**
   * 检查是否拥有所有指定权限
   * @param permissionCodes 权限编码数组
   * @param type 权限类型：'button' | 'menu' | 'url' | 'any'（默认 'any'）
   * @returns true 表示拥有所有权限，false 表示缺少某些权限
   */
  function hasAllPermissions(
    permissionCodes: string[],
    type: 'button' | 'menu' | 'url' | 'any' = 'any',
  ): boolean {
    if (!token.value) return false;
    return permissionCodes.every((code) =>
      hasPermissionInToken(token.value, code, type),
    );
  }

  /**
   * 检查是否拥有指定角色
   * @param role 角色名称（如：'ADMIN'）
   * @returns true 表示拥有角色，false 表示没有角色
   */
  function hasRole(role: string): boolean {
    if (!token.value) return false;
    return hasRoleInToken(token.value, role);
  }

  /**
   * 检查是否拥有任一指定角色
   * @param roleList 角色名称数组
   * @returns true 表示拥有任一角色，false 表示没有任何角色
   */
  function hasAnyRole(roleList: string[]): boolean {
    if (!token.value) return false;
    return hasAnyRoleInToken(token.value, roleList);
  }

  /**
   * 检查是否拥有所有指定角色
   * @param roleList 角色名称数组
   * @returns true 表示拥有所有角色，false 表示缺少某些角色
   */
  function hasAllRoles(roleList: string[]): boolean {
    if (!token.value) return false;
    return hasAllRolesInToken(token.value, roleList);
  }

  /**
   * 检查是否是管理员
   * @returns true 表示是管理员，false 表示不是管理员
   */
  function isAdmin(): boolean {
    return hasRole('ADMIN');
  }

  /**
   * 检查是否拥有按钮权限
   * @param permissionCode 权限编码
   * @returns true 表示拥有权限，false 表示没有权限
   */
  function hasButtonPermission(permissionCode: string): boolean {
    return hasPermission(permissionCode, 'button');
  }

  /**
   * 检查是否拥有菜单权限
   * @param permissionCode 权限编码
   * @returns true 表示拥有权限，false 表示没有权限
   */
  function hasMenuPermission(permissionCode: string): boolean {
    return hasPermission(permissionCode, 'menu');
  }

  /**
   * 检查是否拥有接口权限
   * @param permissionCode 权限编码
   * @returns true 表示拥有权限，false 表示没有权限
   */
  function hasUrlPermission(permissionCode: string): boolean {
    return hasPermission(permissionCode, 'url');
  }

  return {
    // 状态
    token,
    tokenPayload,
    permissions,
    roles,
    userInfo,

    // 权限检查方法
    hasPermission,
    hasAnyPermission,
    hasAllPermissions,
    hasButtonPermission,
    hasMenuPermission,
    hasUrlPermission,

    // 角色检查方法
    hasRole,
    hasAnyRole,
    hasAllRoles,
    isAdmin,
  };
}

